﻿#region

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using Rio.Applications.Web.Services;
using Rio.Framework.Localisation;
using Rio.Framework.Pages.Context;
using Rio.Framework.Pages.Events;
using Rio.Framework.Pages.Helpers.Utils;
using Rio.Framework.WCFService;
using Rio.Framework.WCFService.RioWcfServices;
using BarcodeDocumentSeparator = NetBay.Core.BusinessEntities.Barcodes.BarcodeDocumentSeparator;
using BarcodeFolderSeparator = NetBay.Core.BusinessEntities.Barcodes.BarcodeFolderSeparator;
using BarcodeSeparator = NetBay.Core.BusinessEntities.Barcodes.BarcodeSeparator;
using BarcodeSeparatorType = NetBay.Core.BusinessEntities.Barcodes.BarcodeSeparatorType;
using Document = NetBay.Core.BusinessEntities.Document;
using ImageRio = NetBay.Core.BusinessEntities.ImageRio;

#endregion

namespace Rio.Framework.Pages.Manager
{
    public class BarcodeManager : ManagerBase
    {
        #region Readonly & Static Fields

        private readonly List<ImageRio> _barcodeFilesToDelete;
        private readonly List<BarcodeSeparator> _foundBarcode = new List<BarcodeSeparator>();

        #endregion

        #region Fields

        private int _CptBarcodeDocStart;
        private int _CptBarcodeFolderStart;
        private BusinessEntitiesDomainContext _DataContext;
        private Queue<FolderDataContext> _FolderQueue;
        private bool _addFulltext;
        private string _author;
        private int _counterErrorOnIndex;
        private int _counterIndexedDocOk;
        private DocumentDataContext _currentProcessedDocument;
        private FolderDataContext _currentProcessedFolder;
        private Dictionary<long, string> _defaultCriteria;
        private long? _defaultFolderTypeId;
        private long? _defaultOrganizationId;
        private List<FolderDataContext> _lstFoldersToIndex = new List<FolderDataContext>();
        private string _note;
        private Boolean _startPdfMerge;

        #endregion

        #region Constructors

        public BarcodeManager()
        {
            _FolderQueue = new Queue<FolderDataContext>();
            ProcessedImages = new List<ImageRio>();
            _barcodeFilesToDelete = new List<ImageRio>();
        }

        #endregion

        #region Instance Properties

        public long? DefaultFolderTypeId
        {
            get
            {
                return _defaultFolderTypeId;
            }
        }

        public long? DefaultOrganizationId
        {
            get
            {
                return _defaultOrganizationId;
            }
        }

        public List<BarcodeSeparator> FoundBarcode
        {
            get
            {
                return _foundBarcode;
            }
        }

        /// <summary>
        ///   Gets the processed images.
        /// </summary>
        /// <value> The processed images. </value>
        public List<ImageRio> ProcessedImages { get; private set; }

        #endregion

        #region Instance Methods

        /// <summary>
        ///   Cleans the folders.
        /// </summary>
        /// <param name="foldersToIndexes"> The folders to indexes. </param>
        /// <returns> </returns>
        public List<FolderDataContext> CleanFolders(List<FolderDataContext> foldersToIndexes)
        {
            //Limit Test.
            foldersToIndexes = CleanLimit(foldersToIndexes);

            //Single unique index test.
            foldersToIndexes = CleanSingleUniqueIndex(foldersToIndexes);

            //Delete empty documents.
            foldersToIndexes = CleanEmptyDocumentsDelete(foldersToIndexes);

            return foldersToIndexes;
        }

        /// <summary>
        ///   Clears this instance.
        /// </summary>
        public void Clear()
        {
            _counterIndexedDocOk = 0;
            _counterErrorOnIndex = 0;
            _FolderQueue.Clear();
            ProcessedImages.Clear();
            _barcodeFilesToDelete.Clear();
            _currentProcessedFolder = null;
            _currentProcessedDocument = null;
        }

        /// <summary>
        ///   Delete empty documents.
        /// </summary>
        /// <returns> The good folder list </returns>
        public List<FolderDataContext> CleanEmptyDocumentsDelete(List<FolderDataContext> foldersList)
        {
            List<FolderDataContext> tempFolderList = foldersList;

            //Delete the document empty.
            for (int cptItemFolder = 0; cptItemFolder < tempFolderList.Count; cptItemFolder++)
            {
                if (tempFolderList[cptItemFolder].Documents.Count == 0)
                {
                    tempFolderList.RemoveAt(cptItemFolder);
                    cptItemFolder--;
                }
                else
                {
                    for (int cptItemDocument = 0; cptItemDocument < tempFolderList[cptItemFolder].Documents.Count; cptItemDocument++)
                    {
                        if (tempFolderList[cptItemFolder].Documents[cptItemDocument].ImagesToIndex.Count == 0)
                        {
                            tempFolderList[cptItemFolder].Documents.RemoveAt(cptItemDocument);
                            cptItemDocument--;
                        }
                    }
                    if (tempFolderList[cptItemFolder].Documents.Count == 0)
                    {
                        tempFolderList.RemoveAt(cptItemFolder);
                        cptItemFolder--;
                    }
                }
            }

            return tempFolderList;
        }

        /// <summary>
        ///   Validate limit folders list to indexes
        /// </summary>
        /// <returns> The good folder list </returns>
        public List<FolderDataContext> CleanLimit(List<FolderDataContext> foldersList)
        {
            List<FolderDataContext> tempFolderList = foldersList;

            //Prepare indexing document --> part Limit.
            for (int cptFolderToIndex = 0; cptFolderToIndex < tempFolderList.Count; cptFolderToIndex++)
            {
                //Test all barcode.
                //Part Folder separator.
                if (tempFolderList[cptFolderToIndex].Separator != null)
                {
                    //Case barcode folder separator.
                    if ((tempFolderList[cptFolderToIndex].ErrorDocumentLimit) || (tempFolderList[cptFolderToIndex].ErrorPageLimit))
                    {
                        //The barcode is an error
                        if (tempFolderList[cptFolderToIndex].Separator.ErrorManagment)
                        {
                            //Error and barcode managment error --> delete
                            tempFolderList.RemoveAt(cptFolderToIndex);
                            cptFolderToIndex--;
                            continue;
                        }

                        if (tempFolderList[cptFolderToIndex].ErrorPageLimit)
                        {
                            //Here Barcode separator folder and error page.
                            //Delete page in more or if there are many page --> delete barcode
                            int l_iInf = tempFolderList[cptFolderToIndex].Separator.InfLimit;
                            int l_iSup = tempFolderList[cptFolderToIndex].Separator.SupLimit;
                            int l_iNbPage = tempFolderList[cptFolderToIndex].Documents[0].ImagesToIndex.Count;
                            if (l_iNbPage < l_iInf)
                            {
                                //Delete the document separator.
                                tempFolderList[cptFolderToIndex].Documents.RemoveAt(0);
                                continue;
                            }

                            for (int l_iItemToDelete = l_iSup; l_iItemToDelete < l_iNbPage; l_iItemToDelete++)
                            {
                                //Delete the document separator page in more.
                                tempFolderList[cptFolderToIndex].Documents[0].ImagesToIndex.RemoveAt(l_iSup);
                            }

                            continue;
                        }

                        //Here Barcode separator folder and error document.
                        //Verify first all the barcode to this barcode separator folder.
                        //Error and not in managment error --> delete the necessary.
                        for (int cptDocument = 0; cptDocument < tempFolderList[cptFolderToIndex].Documents.Count; cptDocument++)
                        {
                            if (tempFolderList[cptFolderToIndex].Documents[cptDocument].Separator != null)
                            {
                                //Case barcode document separator.
                                if (tempFolderList[cptFolderToIndex].Documents[cptDocument].ErrorPageLimit)
                                {
                                    if (tempFolderList[cptFolderToIndex].Documents[cptDocument].Separator.ErrorManagment)
                                    {
                                        //Delete the document separator.
                                        tempFolderList[cptFolderToIndex].Documents.RemoveAt(cptDocument);
                                        cptDocument--;
                                    }
                                    else
                                    {
                                        //Delete page in more or if there are many page --> delete barcode
                                        int l_iInf = tempFolderList[cptFolderToIndex].Documents[cptDocument].Separator.InfLimit;
                                        int l_iSup = tempFolderList[cptFolderToIndex].Documents[cptDocument].Separator.SupLimit;
                                        int l_iNbPage = tempFolderList[cptFolderToIndex].Documents[cptDocument].ImagesToIndex.Count;
                                        if (l_iNbPage < l_iInf)
                                        {
                                            //Delete the document separator.
                                            tempFolderList[cptFolderToIndex].Documents.RemoveAt(cptDocument);
                                            cptDocument--;
                                        }
                                        else
                                        {
                                            for (int itemToDelete = l_iSup; itemToDelete < l_iNbPage; itemToDelete++)
                                            {
                                                //Delete the document separator page in more.
                                                tempFolderList[cptFolderToIndex].Documents[cptDocument].ImagesToIndex.RemoveAt(l_iSup);
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                //Case page nothing barcode document separator.
                                if (tempFolderList[cptFolderToIndex].Separator.PageLimit)
                                {
                                    //Delete page in more or if there are many page --> delete barcode
                                    int l_iInf = tempFolderList[cptFolderToIndex].Separator.InfLimit;
                                    int l_iSup = tempFolderList[cptFolderToIndex].Separator.SupLimit;
                                    int l_iNbPage = tempFolderList[cptFolderToIndex].Documents[cptDocument].ImagesToIndex.Count;
                                    if (l_iNbPage < l_iInf)
                                    {
                                        //Delete all page.
                                        tempFolderList[cptFolderToIndex].Documents.RemoveAt(cptDocument);
                                        cptDocument--;
                                    }
                                    else
                                    {
                                        for (int l_iItemToDelete = l_iSup; l_iItemToDelete < l_iNbPage; l_iItemToDelete++)
                                        {
                                            //Delete page in more.
                                            tempFolderList[cptFolderToIndex].Documents[cptDocument].ImagesToIndex.RemoveAt(l_iSup);
                                        }
                                    }
                                }
                            }
                        }

                        //Verify barcode separator folder.
                        //Delete barcode document separator in more or if there are many document --> delete barcode
                        int infLimit = tempFolderList[cptFolderToIndex].Separator.InfLimit;
                        int supLimit = tempFolderList[cptFolderToIndex].Separator.SupLimit;
                        int nbDoc = tempFolderList[cptFolderToIndex].Documents.Count;
                        int pageFirstSup = 0;

                        //First is not document.
                        if (tempFolderList[cptFolderToIndex].Documents[0].Separator == null)
                        {
                            nbDoc--;
                            pageFirstSup = 2;
                        }
                        if (nbDoc < infLimit)
                        {
                            //Delete the document separator.
                            tempFolderList[cptFolderToIndex].Documents.RemoveAt(0);
                            continue;
                        }

                        for (int l_iItemToDelete = supLimit - 1 + pageFirstSup; l_iItemToDelete < nbDoc - 1 + pageFirstSup; l_iItemToDelete++)
                        {
                            //Delete the document separator page in more.
                            tempFolderList[cptFolderToIndex].Documents.RemoveAt(l_iItemToDelete);
                        }
                        continue;
                    }


                    //Verify if barcode separator document is good for this good barcode folder separator.
                    for (int cptDocument = 0; cptDocument < tempFolderList[cptFolderToIndex].Documents.Count; cptDocument++)
                    {
                        if (tempFolderList[cptFolderToIndex].Documents[cptDocument].Separator != null)
                        {
                            //Case barcode document separator.
                            if (tempFolderList[cptFolderToIndex].Documents[cptDocument].ErrorPageLimit)
                            {
                                if (tempFolderList[cptFolderToIndex].Documents[cptDocument].Separator.ErrorManagment)
                                {
                                    //Delete the document separator.
                                    tempFolderList[cptFolderToIndex].Documents.RemoveAt(cptDocument);
                                    cptDocument--;
                                }
                                else
                                {
                                    //Delete page in more or if there are many page --> delete barcode
                                    int infLimit = tempFolderList[cptFolderToIndex].Documents[cptDocument].Separator.InfLimit;
                                    int supLimit = tempFolderList[cptFolderToIndex].Documents[cptDocument].Separator.SupLimit;
                                    int nbPage = tempFolderList[cptFolderToIndex].Documents[cptDocument].ImagesToIndex.Count;

                                    if (nbPage < infLimit)
                                    {
                                        //Delete the document separator.
                                        tempFolderList[cptFolderToIndex].Documents.RemoveAt(cptDocument);
                                        cptDocument--;
                                    }
                                    else
                                    {
                                        for (int l_iItemToDelete = supLimit; l_iItemToDelete < nbPage; l_iItemToDelete++)
                                        {
                                            //Delete the document separator page in more.
                                            tempFolderList[cptFolderToIndex].Documents[cptDocument].ImagesToIndex.RemoveAt(supLimit);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else //Part Document separator.
                {
                    //Case barcode document separator or page.
                    //Check all node.
                    //Here verify all the barcode.
                    for (int cptDocument = 0; cptDocument < tempFolderList[cptFolderToIndex].Documents.Count; cptDocument++)
                    {
                        if (tempFolderList[cptFolderToIndex].Documents[cptDocument].Separator != null)
                        {
                            //Case barcode document separator.
                            if (tempFolderList[cptFolderToIndex].Documents[cptDocument].ErrorPageLimit)
                            {
                                if (tempFolderList[cptFolderToIndex].Documents[cptDocument].Separator.ErrorManagment)
                                {
                                    //Delete the document separator.
                                    tempFolderList[cptFolderToIndex].Documents.RemoveAt(cptDocument);
                                    cptDocument--;
                                }
                                else
                                {
                                    //Delete page in more or if there are many page --> delete barcode
                                    int infLimit = tempFolderList[cptFolderToIndex].Documents[cptDocument].Separator.InfLimit;
                                    int supLimit = tempFolderList[cptFolderToIndex].Documents[cptDocument].Separator.SupLimit;
                                    int nbPage = tempFolderList[cptFolderToIndex].Documents[cptDocument].ImagesToIndex.Count;

                                    if (nbPage < infLimit)
                                    {
                                        //Delete the document separator.
                                        tempFolderList[cptFolderToIndex].Documents.RemoveAt(cptDocument);
                                        cptDocument--;
                                    }
                                    else
                                    {
                                        for (int l_iItemToDelete = supLimit; l_iItemToDelete < nbPage; l_iItemToDelete++)
                                        {
                                            //Delete the document separator page in more.
                                            tempFolderList[cptFolderToIndex].Documents[cptDocument].ImagesToIndex.RemoveAt(supLimit);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //Return Value
            return tempFolderList;
        }

        /// <summary>
        ///   Validate the single unique index.
        /// </summary>
        /// <returns> The good folder list </returns>
        public List<FolderDataContext> CleanSingleUniqueIndex(List<FolderDataContext> foldersList)
        {
            List<FolderDataContext> tempFolderList = foldersList;

            //Prepare indexing document --> Index unique value part.
            for (int cptFolderToIndex = 0; cptFolderToIndex < tempFolderList.Count; cptFolderToIndex++)
            {
                if (tempFolderList[cptFolderToIndex].Separator != null)
                {
                    if ((!tempFolderList[cptFolderToIndex].Separator.RecognizedUniqueIndexValue) && (tempFolderList[cptFolderToIndex].Separator.CorrespondenceFolder))
                    {
                        tempFolderList.RemoveAt(cptFolderToIndex);
                        cptFolderToIndex--;
                    }
                    //else if ((tempFolderList[cptFolderToIndex].Separator.RecognizedUniqueIndexValue) && (tempFolderList[cptFolderToIndex].Separator.CorrespondenceFolder))
                    //{
                    //    //Verify if there is not barcode separator document for deleting. --> Not document in single index unique.
                    //    for (int cptDocToIndex = 1; cptDocToIndex < tempFolderList[cptFolderToIndex].Documents.Count; cptDocToIndex++)
                    //    {
                    //        tempFolderList[cptFolderToIndex].Documents.RemoveAt(cptDocToIndex);
                    //        cptDocToIndex--;
                    //    }
                    //}
                }
            }

            //Return Value.
            return tempFolderList;
        }

        /// <summary>
        /// Cleans the folder without correspondence.
        /// </summary>
        /// <param name="foldersList">The folders list.</param>
        /// <returns></returns>
        public List<FolderDataContext> CleanFolderWithoutCorrespondence(List<FolderDataContext> foldersList)
        {
            List<FolderDataContext> tempFolderList = foldersList;
            for (int cptFolderToIndex = 0; cptFolderToIndex < tempFolderList.Count; cptFolderToIndex++)
            {
                if (tempFolderList[cptFolderToIndex].Separator != null && !tempFolderList[cptFolderToIndex].Separator.CorrespondenceFolder)
                {
                        tempFolderList.RemoveAt(cptFolderToIndex);
                        cptFolderToIndex--;

                }
                else if (tempFolderList[cptFolderToIndex].Separator == null)
                {
                    tempFolderList.RemoveAt(cptFolderToIndex);
                    cptFolderToIndex--;
                }
            }
            return tempFolderList;
        }


        /// <summary>
        ///   Gets the folder blocks to indexes.
        /// </summary>
        /// <returns> </returns>
        public List<FolderDataContext> GetFolderBlocksToIndexes()
        {
            //Variable initialization.
            List<FolderDataContext> folderList = new List<FolderDataContext>();
            FolderDataContext folderBlock = null;
            DocumentDataContext currentDocument = null;
            bool isBarcodeImageInitialized = false;

            //Prepare documents to indexes.
            for (int i = 0; i < ProcessedImages.Count; i++)
            {
                ImageRio CurrentImage = ProcessedImages[i];

                //Rank image test.
                if ((i == 0) || (!isBarcodeImageInitialized))
                {
                    if ((CurrentImage.SeparatorBarcodes.Count == 0) && (!CurrentImage.BarCodePageError)) //******** No barcode
                    {
                        //No barcode on the first page
                        folderBlock = new FolderDataContext
                                          {
                                              Criteria = _defaultCriteria,
                                              Separator = null
                                          };

                        currentDocument = new DocumentDataContext();
                        currentDocument.ImagesToIndex.Add(CurrentImage);

                        isBarcodeImageInitialized = true;
                    }
                    else if ((CurrentImage.SeparatorBarcodes.Count == 1) && (!CurrentImage.BarCodePageError)) //******** Only one barcode
                    {
                        var barcode = CurrentImage.SeparatorBarcodes.Single();

                        switch (barcode.TypeOfBarcode)
                        {
                            case BarcodeSeparatorType.FolderSeparator:
                                {
                                    //The barcode is a folder separator, create and get index critaria
                                    BarcodeFolderSeparator sepBarcode = (BarcodeFolderSeparator) barcode;
                                    folderBlock = new FolderDataContext();

                                    //Unique index Criteria
                                    if (sepBarcode.CorrespondenceFolder)
                                    {
                                        Dictionary<long, string> newCriteria = new Dictionary<long, string>
                                                                                   {
                                                                                       {
                                                                                           sepBarcode.UniqueIndexIdentifier.Value, sepBarcode.RecognizedIndexValue
                                                                                       }
                                                                                   };
                                        folderBlock.Criteria = newCriteria;
                                    }
                                    else
                                    {
                                        folderBlock.Criteria = _defaultCriteria;
                                    }
                                    folderBlock.Separator = sepBarcode;

                                    //Add new document if necesssary
                                    currentDocument = new DocumentDataContext();
                                    if (!barcode.DeleteBarCodePage)
                                    {
                                        currentDocument.ImagesToIndex.Add(CurrentImage);
                                    }
                                    else
                                    {
                                        currentDocument.BarcodeImages.Add(CurrentImage);
                                    }
                                }
                                break;
                            case BarcodeSeparatorType.DocumentSeparator:
                                {
                                    //Create a folder with default criteria, and one document with the item 
                                    BarcodeDocumentSeparator sepBarcode = (BarcodeDocumentSeparator) barcode;
                                    folderBlock = new FolderDataContext();

                                    //Add new document rentDocument
                                    currentDocument = new DocumentDataContext {Separator = sepBarcode};
                                    if (!barcode.DeleteBarCodePage)
                                    {
                                        currentDocument.ImagesToIndex.Add(CurrentImage);
                                    }
                                    else
                                    {
                                        currentDocument.BarcodeImages.Add(CurrentImage);
                                    }
                                }
                                break;
                        }

                        isBarcodeImageInitialized = true;
                    }
                    else if ((CurrentImage.SeparatorBarcodes.Count == 2) && (!CurrentImage.BarCodePageError)) //******* Two barcodes founds
                    {
                        //Barcode separator test:
                        var l_oBarcode = CurrentImage.SeparatorBarcodes.ToList();
                        int folderType, documentType;

                        if ((l_oBarcode[0].TypeOfBarcode == BarcodeSeparatorType.FolderSeparator) && (l_oBarcode[1].TypeOfBarcode == BarcodeSeparatorType.DocumentSeparator))
                        {
                            //Case of the first bc is a folder separator and second is document separator
                            folderType = 0;
                            documentType = 1;
                        }
                        else if ((l_oBarcode[1].TypeOfBarcode == BarcodeSeparatorType.FolderSeparator) && (l_oBarcode[0].TypeOfBarcode == BarcodeSeparatorType.DocumentSeparator))
                        {
                            //Case of the first bc is a document separator and second is folder separator
                            documentType = 0;
                            folderType = 1;
                        }
                        else
                        {
                            //Not supported, goto the next image
                            continue;
                        }

                        //Initialization barcode separator folder.
                        BarcodeFolderSeparator l_oBarcodeSepFolder = (BarcodeFolderSeparator) l_oBarcode[folderType];
                        folderBlock = new FolderDataContext();

                        //Unique index Criteria
                        if (l_oBarcodeSepFolder.CorrespondenceFolder)
                        {
                            Dictionary<long, string> newCriteria = new Dictionary<long, string>();
                            newCriteria.Add(l_oBarcodeSepFolder.UniqueIndexIdentifier.Value, l_oBarcodeSepFolder.RecognizedIndexValue);
                            folderBlock.Criteria = newCriteria;
                        }
                        else
                        {
                            //folderBlock.Criteria = null;
                            folderBlock.Criteria = _defaultCriteria;
                        }
                        folderBlock.Separator = l_oBarcodeSepFolder;

                        //Add new document if necesssary
                        currentDocument = new DocumentDataContext();
                        if (!l_oBarcode[folderType].DeleteBarCodePage)
                        {
                            currentDocument.ImagesToIndex.Add(CurrentImage);
                        }
                        else
                        {
                            currentDocument.BarcodeImages.Add(CurrentImage);
                        }

                        //Initialization barcode separator document.
                        BarcodeDocumentSeparator l_oBarcodeSepDocument = (BarcodeDocumentSeparator) l_oBarcode[documentType];

                        //Add new document rentDocument
                        currentDocument = new DocumentDataContext {Separator = l_oBarcodeSepDocument};
                        if (!l_oBarcode[documentType].DeleteBarCodePage)
                        {
                            currentDocument.ImagesToIndex.Add(CurrentImage);
                        }
                        else
                        {
                            currentDocument.BarcodeImages.Add(CurrentImage);
                        }

                        isBarcodeImageInitialized = true;
                    }
                }
                else
                {
                    if ((CurrentImage.SeparatorBarcodes.Count == 0) && (!CurrentImage.BarCodePageError)) //********* No barcode
                    {
                        currentDocument.ImagesToIndex.Add(CurrentImage);
                    }
                    else if ((CurrentImage.SeparatorBarcodes.Count == 1) && (!CurrentImage.BarCodePageError)) //********* only one barcode
                    {
                        //One barcode on the page.
                        var barcode = CurrentImage.SeparatorBarcodes.Single();

                        switch (barcode.TypeOfBarcode)
                        {
                            case BarcodeSeparatorType.FolderSeparator: //The barcode is a folder separator,
                                {
                                    BarcodeFolderSeparator sepBarcode = (BarcodeFolderSeparator) barcode;

                                    folderBlock.Documents.Add(currentDocument);
                                    folderList.Add(folderBlock);
                                    folderBlock = new FolderDataContext();

                                    //Unique index Criteria
                                    if (sepBarcode.CorrespondenceFolder && !string.IsNullOrEmpty(sepBarcode.RecognizedIndexValue))
                                    {
                                        Dictionary<long, string> newCriteria = new Dictionary<long, string>();
                                        newCriteria.Add(sepBarcode.UniqueIndexIdentifier.Value, sepBarcode.RecognizedIndexValue);
                                        folderBlock.Criteria = newCriteria;
                                    }
                                    else
                                    {
                                        //folderBlock.Criteria = null;
                                        folderBlock.Criteria = _defaultCriteria;
                                    }
                                    folderBlock.Separator = sepBarcode;

                                    //Add new document 
                                    currentDocument = new DocumentDataContext();

                                    //Keep or remove CB page
                                    if (!barcode.DeleteBarCodePage)
                                    {
                                        currentDocument.ImagesToIndex.Add(CurrentImage);
                                    }
                                    else
                                    {
                                        currentDocument.BarcodeImages.Add(CurrentImage);
                                    }
                                }
                                break;
                            case BarcodeSeparatorType.DocumentSeparator: //The barcode is a document separator,
                                {
                                    BarcodeDocumentSeparator sepBarcode = (BarcodeDocumentSeparator) barcode;
                                    
                                    //case of a folder separator before this barcode
                                    List<ImageRio> imgcb = null;
                                    if (currentDocument != null)
                                    {
                                        imgcb = currentDocument.BarcodeImages;
                                    }

                                    //Add new document 
                                    folderBlock.Documents.Add(currentDocument);
                                    currentDocument = new DocumentDataContext {Separator = sepBarcode};

                                    //Keep or remove CB page
                                    if (!barcode.DeleteBarCodePage)
                                    {
                                        if (imgcb != null)
                                        {
                                            currentDocument.ImagesToIndex.AddRange(imgcb);
                                        }
                                        currentDocument.ImagesToIndex.Add(CurrentImage);
                                    }
                                    else
                                    {
                                        if (imgcb != null)
                                        {
                                            currentDocument.BarcodeImages.AddRange(imgcb);
                                        }
                                        currentDocument.BarcodeImages.Add(CurrentImage);
                                    }
                                }
                                break;
                        }
                    }
                    else if ((CurrentImage.SeparatorBarcodes.Count == 2) && (!CurrentImage.BarCodePageError)) //********* Two barcode and no error found
                    {
                        var barcode = CurrentImage.SeparatorBarcodes.ToList();
                        int folderType, documentType;

                        if ((barcode[0].TypeOfBarcode == BarcodeSeparatorType.FolderSeparator) && (barcode[1].TypeOfBarcode == BarcodeSeparatorType.DocumentSeparator))
                        {
                            folderType = 0;
                            documentType = 1;
                        }
                        else if ((barcode[1].TypeOfBarcode == BarcodeSeparatorType.FolderSeparator) && (barcode[0].TypeOfBarcode == BarcodeSeparatorType.DocumentSeparator))
                        {
                            documentType = 0;
                            folderType = 1;
                        }
                        else
                        {
                            //Not implemented case, goto the next image
                            continue;
                        }

                        //Initialization barcode separator folder.
                        BarcodeFolderSeparator l_oBarcodeSepFolder = (BarcodeFolderSeparator) barcode[folderType];
                        folderBlock.Documents.Add(currentDocument);
                        folderList.Add(folderBlock);
                        folderBlock = new FolderDataContext();

                        //Unique index Criteria
                        if (l_oBarcodeSepFolder.CorrespondenceFolder)
                        {
                            Dictionary<long, string> newCriteria = new Dictionary<long, string>();
                            newCriteria.Add(l_oBarcodeSepFolder.UniqueIndexIdentifier.Value, l_oBarcodeSepFolder.RecognizedIndexValue);
                            folderBlock.Criteria = newCriteria;
                        }
                        else
                        {
                            folderBlock.Criteria = _defaultCriteria;
                        }
                        folderBlock.Separator = l_oBarcodeSepFolder;

                        //Add new document if necesssary
                        currentDocument = new DocumentDataContext();

                        //Keep or remove foldertype page
                        if (!barcode[folderType].DeleteBarCodePage)
                        {
                            currentDocument.ImagesToIndex.Add(CurrentImage);
                        }
                        else
                        {
                            currentDocument.BarcodeImages.Add(CurrentImage);
                        }

                        //Initialization barcode separator document.
                        BarcodeDocumentSeparator barcodeSepDocument = (BarcodeDocumentSeparator) barcode[documentType];

                        //Add new document rentDocument
                        currentDocument = new DocumentDataContext {Separator = barcodeSepDocument};

                        //Keep or remove documenttype page
                        if (!barcode[documentType].DeleteBarCodePage)
                        {
                            currentDocument.ImagesToIndex.Add(CurrentImage);
                        }
                        else
                        {
                            currentDocument.BarcodeImages.Add(CurrentImage);
                        }
                    }
                }
            }

            //Value object.
            if (folderBlock != null)
            {
                folderBlock.Documents.Add(currentDocument);
            }

            if (folderBlock != null)
            {
                folderList.Add(folderBlock);
            }

            //Return value.
            return folderList;
        }

        /// <summary>
        ///   Pres the process barcode.
        /// </summary>
        /// <param name="images"> </param>
        /// <param name="organizationId"> The organization id. </param>
        /// <param name="folderTypeId"> The folder type id. </param>
        /// <param name="defaultCriteria"> </param>
        /// <param name="addDocumentFullText"> </param>
        /// <param name="note"> </param>
        /// <param name="author"> </param>
        public void PreProcessBarcode(List<string> images, long? organizationId, long? folderTypeId, Dictionary<long, string> defaultCriteria, bool addDocumentFullText, string note, string author)
        {
            Clear();

            _defaultOrganizationId = organizationId;
            _defaultFolderTypeId = folderTypeId;
            _defaultCriteria = defaultCriteria;
            _addFulltext = addDocumentFullText;
            _note = note;
            _author = author;

            var query = GetDataContext.RunBarcodeProcessingOnImportFilesQuery(images, organizationId, folderTypeId, GlobalWebContext.CurrentUser.UserId);
            GetDataContext.Load(query, OnRunBarcodeProcessingOnImportFilesQueryCallback, null);
        }

        /// <summary>
        ///   Prepare all the document to indexes
        /// </summary>
        public void ProcessFolders(List<FolderDataContext> foldersToIndexes)
        {
            _CptBarcodeFolderStart = 0;
            _CptBarcodeDocStart = 0;
            ProcessFolderInternal(CleanFolders(foldersToIndexes), _CptBarcodeFolderStart, _CptBarcodeDocStart);
        }

        /// <summary>
        ///   Called when [barcode processed].
        /// </summary>
        protected void OnBarcodeProcessed()
        {
            if (BarcodeProcessed != null)
            {
                BarcodeProcessed(this, new BarcodeEventArgs(ProcessedImages));
            }
        }

        /// <summary>
        /// Called when [before indexing].
        /// </summary>
        protected void OnBeforeIndexing()
        {
            if (BeforeIndexing != null)
            {
                BeforeIndexing(this, new EventArgs());
            }
        }

        /// <summary>
        /// Called when [indexing aborted].
        /// </summary>
        protected void OnIndexingAborted()
        {
            if (IndexingAborted != null)
            {
                IndexingAborted(this, new EventArgs());
            }
        }

        /// <summary>
        ///   Called when [indexing finished].
        /// </summary>
        protected void OnIndexingError(string error)
        {
            if (IndexingError != null)
            {
                IndexingError(this, new BarcodeEventArgs(error, 0));
            }
        }

        /// <summary>
        ///   Called when [indexing finished].
        /// </summary>
        protected void OnIndexingFinished()
        {
            if (IndexingFinished != null)
            {
                BarcodeEventArgs args = new BarcodeEventArgs(ProcessedImages)
                                            {
                                                ProcessedFilesCount = _counterIndexedDocOk,
                                                ErrorFilesCount = _counterErrorOnIndex
                                            };
                IndexingFinished(this, args);
            }
        }

        /// <summary>
        ///   Called when [barcode processed].
        /// </summary>
        protected void OnNeedIndexCriteria()
        {
            if (NeedIndexCriteria != null)
            {
                NeedIndexCriteria(this, new BarcodeIndexingEventArgs());
            }
        }

        /// <summary>
        ///   Called when [barcode processed].
        /// </summary>
        protected void OnNonUnicity()
        {
            if (NonUnicity != null)
            {
                NonUnicity(this, new BarcodeIndexingEventArgs());
            }
        }

        /// <summary>
        ///   Called when [indexing finished].
        /// </summary>
        protected void OnProcessingError(string error)
        {
            if (ProcessingError != null)
            {
                ProcessingError(this, new BarcodeEventArgs(error, 0));
            }
        }

        /// <summary>
        ///   Invokes the add document query.
        /// </summary>
        private void AddDocuments()
        {
            //Variable initialization.

            if (_currentProcessedFolder != null)
            {
                string itemCode = "000000000000";

                //Get next block
                if (_currentProcessedFolder.Documents.Count > 0)
                {
                    _currentProcessedDocument = _currentProcessedFolder.Documents.First();
                    _currentProcessedFolder.Documents.RemoveAt(0);
                }
                else if (_FolderQueue.Count > 0)
                {
                    _currentProcessedFolder = _FolderQueue.Dequeue();
                    _currentProcessedDocument = _currentProcessedFolder.Documents.First();
                    _currentProcessedFolder.Documents.RemoveAt(0);
                }

                //Set itemcode
                if (_currentProcessedDocument.Separator != null)
                    itemCode = _currentProcessedDocument.Separator.ItemCode;

                //Files to import
                List<String> files = _currentProcessedDocument.ImagesToIndex.Select(p => Utils.RemoveExtension(p.Name)).ToList();

                //Check index values
                _currentProcessedFolder.Criteria = _currentProcessedFolder.Criteria ?? _defaultCriteria;
                if (_currentProcessedFolder.Criteria == null)
                {
                    //Raise needindex event in case unicity index.
                    BarcodeIndexingEventArgs args = new BarcodeIndexingEventArgs();
                    args.DataContext = _currentProcessedFolder;
                    NeedIndexCriteria(this, args);

                    if (args.Cancel)
                    {
                        //Abort indexing
                        OnIndexingAborted();
                        return;
                    }

                    if (args.NewCriteria != null)
                    {
                        _currentProcessedFolder.Criteria = args.NewCriteria;
                    }
                    else
                    {
                        //Abort indexing
                        OnIndexingAborted();
                        return;
                    }
                }

                //Retrieves Organization and folder type.
                long defaultOrganizationId;
                long defaultFolderTypeId;
                if ((_currentProcessedFolder.Separator == null) || (!_currentProcessedFolder.Separator.CorrespondenceFolder))
                {
                    //get default
                    defaultOrganizationId = _defaultOrganizationId.Value;
                    defaultFolderTypeId = _defaultFolderTypeId.Value;
                }
                else
                {
                    defaultOrganizationId = _currentProcessedFolder.Separator.OrganizationId;
                    defaultFolderTypeId = _currentProcessedFolder.Separator.FolderTypeId;
                }

                //Indexing.
                InvokeAddDocumentsQuery(files, _currentProcessedFolder.Criteria ?? _defaultCriteria,
                                        itemCode, _currentProcessedDocument, defaultOrganizationId, defaultFolderTypeId);
            }
        }

        /// <summary>
        ///   Deletes the barcode files.
        /// </summary>
        private void DeleteBarcodeFiles(List<ImageRio> images)
        {
            if (images != null && images.Count > 0)
            {
                WCFServiceClient WCFServiceClient = ServiceManager.GetRioWCFServiceClient();
                WCFServiceClient.DeleteImportDocumentCompleted += L_oWCFServiceClient_DeleteImportDocumentCompleted;
                WCFServiceClient.DeleteImportDocumentAsync(new ObservableCollection<string>(images.Select(p => Utils.RemoveExtension(p.Name)).ToList()), GlobalWebContext.CurrentUser.UserId,
                                                           ServiceManager.GetLicenseKey());
            }
        }

        /// <summary>
        ///   Invokes the add documents query.
        /// </summary>
        /// <param name="files"> The files. </param>
        /// <param name="criteria"> </param>
        /// <param name="itemCode"> The item code. </param>
        /// <param name="context"> The context. </param>
        /// <param name="organization"> </param>
        /// <param name="folderTypeId"> </param>
        private void InvokeAddDocumentsQuery(IEnumerable<string> files, Dictionary<long, string> criteria, string itemCode, DocumentDataContext context, long organization, long folderTypeId)
        {
            //Built query variable.
            var query = GetDataContext.AddDocumentQuery(organization,
                                                        folderTypeId,
                                                        criteria,
                                                        files,
                                                        itemCode,
                                                        _note,
                                                        _author,
                                                        string.Empty,
                                                        string.Empty,
                                                        0,
                                                        true);

            //Execute query.
            GetDataContext.Load(query, OnAddDocumentQueryCallback, context);
        }

        /// <summary>
        ///   Occurs when a document was added to RIO Call MoveImportDocument Wcf
        /// </summary>
        /// <param name="result"> The result. </param>
        private void OnAddDocumentQueryCallback(LoadOperation<Document> result)
        {
            try
            {
                DocumentDataContext currentBlock = result.UserState as DocumentDataContext;
                List<Document> l_oReturnObjects = new List<Document>(result.Entities);

                if (l_oReturnObjects.Count > 0)
                {
                    Document l_oFirst = l_oReturnObjects.First();
                    if (l_oFirst.IsValid)
                    {
                        ObservableCollection<WCFService.RioWcfServices.Document> l_oObservableCollection = new ObservableCollection<WCFService.RioWcfServices.Document>();
                        foreach (Document l_oDoc in l_oReturnObjects)
                        {
                            WCFService.RioWcfServices.Document l_oWCFDoc = new WCFService.RioWcfServices.Document
                                                                               {
                                                                                   Identifier = l_oDoc.Identifier,
                                                                                   ImageName = l_oDoc.ImageName,
                                                                                   RelativePath = l_oDoc.RelativePath,
                                                                                   MultiVolumePath = l_oDoc.MultiVolumePath
                                                                               };

                            l_oObservableCollection.Add(l_oWCFDoc);
                        }

                        //Move the physical document which has been indexed
                        WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();
                        L_oWCFServiceClient.MoveImportDocumentCompleted += MoveImportDocumentCompleted;
                        L_oWCFServiceClient.MoveImportDocumentAsync(l_oObservableCollection, GlobalWebContext.CurrentUser.UserId, ServiceManager.GetLicenseKey(), result.UserState);
                    }
                    else
                    {
                        throw new Exception(l_oFirst.ErrorMessage);
                    }
                }
                else
                {
                    //Add barcode images 
                    if (currentBlock != null && (currentBlock.BarcodeImages != null && currentBlock.BarcodeImages.Count > 0))
                        _barcodeFilesToDelete.AddRange(currentBlock.BarcodeImages);

                    //There is allready images to index
                    if (_FolderQueue.Count > 0 || _currentProcessedFolder.Documents.Count > 0)
                    {
                        AddDocuments();
                    }
                    else
                    {
                        if (_barcodeFilesToDelete.Count > 0)
                        {
                            DeleteBarcodeFiles(_barcodeFilesToDelete);
                        }
                        else
                        {
                            OnIndexingFinished();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception("OnAddDocumentQueryCallback : " + ex.Message);
            }
        }

        /// <summary>
        ///   Called when [run barcode processing on import files query callback].
        /// </summary>
        /// <param name="result"> The result. </param>
        private void OnRunBarcodeProcessingOnImportFilesQueryCallback(LoadOperation<ImageRio> result)
        {
            if (result.HasError)
            {
                OnProcessingError(result.Error.Message);
            }
            else
            {
                ProcessedImages = new List<ImageRio>(result.Entities);

                _foundBarcode.Clear();
                foreach (var processedImage in ProcessedImages)
                {
                    if (processedImage.SeparatorBarcodes != null)
                        _foundBarcode.AddRange(processedImage.SeparatorBarcodes);
                }

                OnBarcodeProcessed();
            }
        }

        /// <summary>
        ///   Merge Pdf Document if necessary.
        /// </summary>
        /// <param name="foldersList"> Object folders to indexes. </param>
        /// <param name="barcodeSepFolderStart"> Couter to start the barcode. </param>
        /// <param name="barcodeSepDocStart"> Couter to start the document barcode. </param>
        private void ProcessFolderInternal(List<FolderDataContext> foldersList, int barcodeSepFolderStart, int barcodeSepDocStart)
        {
            _startPdfMerge = false;

            //For each folders 
            for (int cptFolderToIndex = barcodeSepFolderStart; cptFolderToIndex < foldersList.Count; cptFolderToIndex++)
            {
                //For each documents in folder 
                for (int cptDocumentToIndex = barcodeSepDocStart; cptDocumentToIndex < foldersList[cptFolderToIndex].Documents.Count; cptDocumentToIndex++)
                {
                    if ((foldersList[cptFolderToIndex].Documents[cptDocumentToIndex].Separator != null) && (foldersList[cptFolderToIndex].Documents[cptDocumentToIndex].Separator.PdfMerge))
                    {
                        //Get all images to merge in the current block
                        List<string> l_sLstImageToMerge = new List<string>();
                        for (int cptImage = 0; cptImage < foldersList[cptFolderToIndex].Documents[cptDocumentToIndex].ImagesToIndex.Count; cptImage++)
                        {
                            l_sLstImageToMerge.Add(Utils.RemoveExtension(foldersList[cptFolderToIndex].Documents[cptDocumentToIndex].ImagesToIndex[cptImage].Name));
                        }

                        //Launch pdf treatment.
                        _lstFoldersToIndex = new List<FolderDataContext>(foldersList);
                        PdfManager pdfManager = new PdfManager(l_sLstImageToMerge, false, GlobalWebContext.CurrentUser.UserId);
                        pdfManager.MergePDFCompleted += pdfManager_MergePDFCompleted;
                        pdfManager.ImportedDocumentMergeFailed += pdfManager_ImportedDocumentMergeFailed;
                        pdfManager.MergeDocumentsListInPdf();
                        _CptBarcodeFolderStart = cptFolderToIndex;
                        _CptBarcodeDocStart = cptDocumentToIndex;
                        _startPdfMerge = true;

                        break;
                    }
                }
            }

            //Lauch indexing if not merging pdf
            if (!_startPdfMerge)
            {
                //Dans le terminé final compléted.
                if (foldersList.Count != 0)
                {
                    RunIndexingInternal(foldersList);
                }
            }
        }

        /// <summary>
        ///   Runs the indexing.
        /// </summary>
        private void RunIndexingInternal(IEnumerable<FolderDataContext> foldersToIndexes)
        {
            _FolderQueue = new Queue<FolderDataContext>(foldersToIndexes);
            _currentProcessedFolder = _FolderQueue.Dequeue();
            OnBeforeIndexing();
            AddDocuments();
        }

        #endregion

        #region Event Handling

        /// <summary>
        ///   Handles the DeleteImportDocumentCompleted event of the L_oWCFServiceClient control.
        /// </summary>
        /// <param name="sender"> The source of the event. </param>
        /// <param name="e"> The <see cref="Rio.Framework.WCFService.RioWcfServices.DeleteImportDocumentCompletedEventArgs" /> instance containing the event data. </param>
        private void L_oWCFServiceClient_DeleteImportDocumentCompleted(object sender, DeleteImportDocumentCompletedEventArgs e)
        {
            OnIndexingFinished();
        }

        /// <summary>
        ///   Moves the import document completed.
        /// </summary>
        /// <param name="sender"> The sender. </param>
        /// <param name="e"> The <see cref="Rio.Framework.WCFService.RioWcfServices.MoveImportDocumentCompletedEventArgs" /> instance containing the event data. </param>
        private void MoveImportDocumentCompleted(object sender, MoveImportDocumentCompletedEventArgs e)
        {
            ObservableCollection<WCFService.RioWcfServices.Document> l_oObservableCollection = e.Result;
            DocumentDataContext currentBlock = e.UserState as DocumentDataContext;
            bool hasError = false;
            List<String> l_oDocumentIdentifierList = new List<string>();

            foreach (WCFService.RioWcfServices.Document l_oDoc in l_oObservableCollection)
            {
                if (!String.IsNullOrEmpty(l_oDoc.ErrorMessage))
                {
                    _counterErrorOnIndex++;
                    hasError = true;

                    try
                    {
                        var query = GetDataContext.RemoveDocumentQuery(l_oDoc.Identifier);
                        GetDataContext.Load(query, null, null);
                    }
                    catch (Exception ex)
                    {
                        OnIndexingError(string.Format("MoveImportDocumentCompleted {0}", ex.Message));
                    }
                }
                else
                {
                    l_oDocumentIdentifierList.Add(Convert.ToString(l_oDoc.Identifier));
                    _counterIndexedDocOk++;
                }
            }

            //Add documents fulltext
            if (l_oDocumentIdentifierList.Count > 0 && _addFulltext)
            {
                GetDataContext.UpdateDocumentsForFullText(String.Join(",", l_oDocumentIdentifierList.ToArray()));
            }

            //Next bundles if no error
            if (hasError)
            {
                OnIndexingError("Une erreur s'est produite durant le déplacement des fichiers!");
            }
            else
            {
                //Add barcode images 
                if (currentBlock != null && (currentBlock.BarcodeImages != null && currentBlock.BarcodeImages.Count > 0))
                    _barcodeFilesToDelete.AddRange(currentBlock.BarcodeImages);

                //There is allready images to index
                if (_FolderQueue.Count > 0 || _currentProcessedFolder.Documents.Count > 0)
                {
                    AddDocuments();
                }
                else
                {
                    if (_barcodeFilesToDelete.Count > 0)
                    {
                        DeleteBarcodeFiles(_barcodeFilesToDelete);
                    }
                    else
                    {
                        OnIndexingFinished();
                    }
                }
            }
        }

        /// <summary>
        ///   Aborted pdfManager.
        /// </summary>
        /// <param name="sender"> </param>
        /// <param name="args"> FileName PDF Merging </param>
        private void pdfManager_ImportedDocumentMergeFailed(object sender, ImportedDocumentMergeFailedEventArgs args)
        {
            //User message.
            MessageBoxChildWindow L_oMessage = new MessageBoxChildWindow(Resx.GetLabel(ResxIndexPanel.MSG_TITLE_PDF_MERGE_ERROR),
                                                                         string.Format(Resx.GetLabel(ResxIndexPanel.MSG_PDF_MERGE_ERROR),
                                                                                       _lstFoldersToIndex[_CptBarcodeFolderStart].Documents[_CptBarcodeDocStart].Separator.NatureName),
                                                                         MessageBoxButtons.Ok, MessageBoxIcon.Warning);
            L_oMessage.Show();
            L_oMessage.Closed += (s, ev) =>
                                     {
                                         //Delete Barcode separaor document not in pdf.
                                         _lstFoldersToIndex[_CptBarcodeFolderStart].Documents.RemoveAt(_CptBarcodeDocStart);

                                         //Recall pdfMerge.
                                         ProcessFolderInternal(_lstFoldersToIndex, _CptBarcodeFolderStart, _CptBarcodeDocStart);
                                     };
        }

        /// <summary>
        ///   Completed pdfManager.
        /// </summary>
        /// <param name="sender"> </param>
        /// <param name="args"> FileName PDF Merging </param>
        private void pdfManager_MergePDFCompleted(object sender, MergePDFCompletedEventArgs args)
        {
            //Variable initialization.
            string pdfFileFullPath = args.PdfFileName;
            pdfFileFullPath = Path.GetFileName(pdfFileFullPath) + ".jpg";

            //Replace documents list by new document pdf.
            for (int i = 0; i < _lstFoldersToIndex[_CptBarcodeFolderStart].Documents[_CptBarcodeDocStart].ImagesToIndex.Count; i++)
            {
                _lstFoldersToIndex[_CptBarcodeFolderStart].Documents[_CptBarcodeDocStart].ImagesToIndex.RemoveAt(i);
                i--;
            }
            ImageRio l_oImageToIndex = new ImageRio {Name = pdfFileFullPath};
            _lstFoldersToIndex[_CptBarcodeFolderStart].Documents[_CptBarcodeDocStart].ImagesToIndex.Add(l_oImageToIndex);

            //continue merge.
            ProcessFolderInternal(_lstFoldersToIndex, _CptBarcodeFolderStart, _CptBarcodeDocStart + 1);
        }

        #endregion

        #region Event Declarations

        public event BarcodeEventHandler BarcodeProcessed;
        public event EventHandler BeforeIndexing;

        public event EventHandler IndexingAborted;
        public event BarcodeEventHandler IndexingError;
        public event BarcodeEventHandler IndexingFinished;
        public event BarcodeIndexingEventHandler NeedIndexCriteria;
        public event BarcodeIndexingEventHandler NonUnicity;
        public event BarcodeEventHandler ProcessingError;

        #endregion

        #region Nested type: DocumentDataContext

        public class DocumentDataContext
        {
            #region Constructors

            /// <summary>
            ///   Initializes a new instance of the <see cref="DocumentDataContext" /> class.
            /// </summary>
            public DocumentDataContext()
            {
                ImagesToIndex = new List<ImageRio>();
                BarcodeImages = new List<ImageRio>();
                Separator = null;
            }

            /// <summary>
            ///   Initializes a new instance of the <see cref="DocumentDataContext" /> class.
            /// </summary>
            /// <param name="separator"> The separator. </param>
            /// <param name="imagesToIndex"> Index of the images to. </param>
            public DocumentDataContext(BarcodeDocumentSeparator separator, List<ImageRio> imagesToIndex)
            {
                Separator = separator;
                BarcodeImages = new List<ImageRio>();
                ImagesToIndex = imagesToIndex;
            }

            #endregion

            #region Instance Properties

            /// <summary>
            ///   Gets or sets the barcode images.
            /// </summary>
            /// <value> The barcode images. </value>
            public List<ImageRio> BarcodeImages { get; set; }

            /// <summary>
            ///   Gets or sets the default criteria.
            /// </summary>
            /// <value> The default criteria. </value>
            public Dictionary<long, string> Criteria { get; set; }

            /// <summary>
            ///   Gets Error Page Limit.
            /// </summary>
            /// <value> The Error Page Limit. </value>
            public Boolean ErrorPageLimit { get; set; }

            /// <summary>
            ///   Gets or sets the index of the images to.
            /// </summary>
            /// <value> The index of the images to. </value>
            public List<ImageRio> ImagesToIndex { get; set; }

            /// <summary>
            ///   Gets the name.
            /// </summary>
            /// <value> The name. </value>
            public string Name
            {
                get
                {
                    //Variable initialization for barcode page.
                    Boolean l_bErrorPage = false;

                    try
                    {
                        //Initialize Barcode Name.
                        string l_sBarcodeName = Separator.BarcodeName != null ? Separator.BarcodeName + " - " : string.Empty;

                        //Test on this barcode.
                        string name;
                        if ((Separator.InfLimit == 0) && (Separator.SupLimit == 0))
                        {
                            name = string.Format("{0} ({1})", Separator != null ? l_sBarcodeName + Separator.NatureName : Resx.GetLabel(ResxIndexPanel.ITEM_NOCLASSED), ImagesToIndex.Count);
                        }
                        else
                        {
                            if (ValidatePageLimit())
                            {
                                name = string.Format("{0} ({1})", Separator != null ? l_sBarcodeName + Separator.NatureName : Resx.GetLabel(ResxIndexPanel.ITEM_NOCLASSED), ImagesToIndex.Count);
                            }
                            else
                            {
                                l_bErrorPage = true;
                                ErrorPageLimit = true;
                                name = string.Format("{0} ({1})", Separator != null ? l_sBarcodeName + Separator.NatureName : Resx.GetLabel(ResxIndexPanel.ITEM_NOCLASSED), ImagesToIndex.Count) +
                                       " " + string.Format(Resx.GetLabel(ResxCommon.BARCODE_RESULT_WINDOW_ERROR_DOCUMENT_LIMIT), Separator.InfLimit, Separator.SupLimit);
                            }
                        }

                        if (Separator.PdfMerge)
                        {
                            name = name + " " + Resx.GetLabel(ResxCommon.BARCODE_RESULT_WINDOW_MSG_DOC_MERGE_PDF);
                        }

                        //Return value?
                        if (Separator.ErrorManagment)
                        {
                            return name;
                        }
                        if (Separator.PdfMerge)
                        {
                            return string.Format("{0} ({1})", Separator != null ? l_sBarcodeName + Separator.NatureName : Resx.GetLabel(ResxIndexPanel.ITEM_NOCLASSED), ImagesToIndex.Count) + " " +
                                   Resx.GetLabel(ResxCommon.BARCODE_RESULT_WINDOW_MSG_DOC_MERGE_PDF);
                        }
                        return string.Format("{0} ({1})", Separator != null ? l_sBarcodeName + Separator.NatureName : Resx.GetLabel(ResxIndexPanel.ITEM_NOCLASSED), ImagesToIndex.Count);
                    }
                    catch (Exception)
                    {
                        //Not Barcode in the first document.
                        ErrorPageLimit = l_bErrorPage;
                        return string.Format("{0} ({1})", Resx.GetLabel(ResxIndexPanel.ITEM_NOCLASSED), ImagesToIndex.Count);
                    }
                }
            }

            /// <summary>
            ///   Gets or sets the separator.
            /// </summary>
            /// <value> The separator. </value>
            public BarcodeDocumentSeparator Separator { get; set; }

            #endregion

            #region Instance Methods

            /// <summary>
            ///   Valides the page limit.
            /// </summary>
            /// <returns> </returns>
            public bool ValidatePageLimit()
            {
                if (Separator != null && Separator.DocLimit)
                {
                    if (Separator.InfLimit <= ImagesToIndex.Count && ImagesToIndex.Count <= Separator.SupLimit)
                    {
                        return true;
                    }
                    return false;
                }
                return true;
            }

            #endregion
        }

        #endregion

        #region Nested type: FolderDataContext

        public class FolderDataContext
        {
            #region Constructors

            /// <summary>
            ///   Initializes a new instance of the <see cref="FolderDataContext" /> class.
            /// </summary>
            public FolderDataContext()
            {
                Documents = new List<DocumentDataContext>();
            }

            #endregion

            #region Instance Properties

            /// <summary>
            ///   Gets or sets the default criteria.
            /// </summary>
            /// <value> The default criteria. </value>
            public Dictionary<long, string> Criteria { get; set; }

            /// <summary>
            ///   Gets or sets the documents.
            /// </summary>
            /// <value> The documents. </value>
            public List<DocumentDataContext> Documents { get; set; }

            /// <summary>
            ///   Gets Error Document Limit.
            /// </summary>
            /// <value> The Error Document Limit. </value>
            public Boolean ErrorDocumentLimit { get; set; }

            /// <summary>
            ///   Gets Error Page Limit.
            /// </summary>
            /// <value> The Error Page Limit. </value>
            public Boolean ErrorPageLimit { get; set; }

            /// <summary>
            ///   Gets the name.
            /// </summary>
            /// <value> The name. </value>
            public string Name
            {
                get
                {
                    //Variable initialization for barcode page.
                    int l_iBarcodePage = 0;
                    Boolean l_bErrorPage = false;
                    Boolean l_bErrorDocument = false;

                    try
                    {
                        //Initialize Folder Name.
                        string barcodeName = Separator.BarcodeName ?? Resx.GetLabel(ResxIndexPanel.FOLDER);

                        //Test on this barcode.
                        if ((Separator.DocumentLimit) && (Separator.DeleteBarCodePage) &&
                            (Documents[0].Name.Substring(0, (Resx.GetLabel(ResxIndexPanel.ITEM_NOCLASSED)).Length) == Resx.GetLabel(ResxIndexPanel.ITEM_NOCLASSED)))
                        {
                            l_iBarcodePage = -1;
                        }

                        //Limit Test.
                        string name;
                        if (Separator.DocLimit)
                        {
                            if (Separator.DocumentLimit)
                            {
                                if (ValidateDocumentLimit(l_iBarcodePage))
                                {
                                    name = string.Format("{0} ({1}) {2}", barcodeName, Documents.Count,
                                                         Separator.UniqueIndexIdentifier != null ? " - " + Separator.UniqueIndexLabel + ": '" + Separator.RecognizedIndexValue + "'" : string.Empty);
                                }
                                else
                                {
                                    ErrorDocumentLimit = true;
                                    l_bErrorDocument = true;
                                    name = string.Format("{0}{1} ({2}) {3}", barcodeName,
                                                         Separator.UniqueIndexIdentifier != null ? " - " + Separator.UniqueIndexLabel + ": '" + Separator.RecognizedIndexValue + "'" : string.Empty,
                                                         Documents.Count + l_iBarcodePage,
                                                         string.Format(Resx.GetLabel(ResxCommon.BARCODE_RESULT_WINDOW_ERROR_FOLDER_LIMIT),
                                                                       Resx.GetLabel(ResxIndexPanel.BARCODE_DOCUMENT_LABEL).ToLower(), Separator.InfLimit, Separator.SupLimit));
                                }
                            }
                            else
                            {
                                if (ValidatePageLimit())
                                {
                                    name = string.Format("{0} ({1}) {2}", barcodeName, Documents.Count,
                                                         Separator.UniqueIndexIdentifier != null ? " - " + Separator.UniqueIndexLabel + ": '" + Separator.RecognizedIndexValue + "'" : string.Empty);
                                }
                                else
                                {
                                    ErrorPageLimit = true;
                                    l_bErrorPage = true;
                                    name = string.Format("{0}{1} ({2}) {3}", barcodeName,
                                                         Separator.UniqueIndexIdentifier != null ? " - " + Separator.UniqueIndexLabel + ": '" + Separator.RecognizedIndexValue + "'" : string.Empty,
                                                         Documents.Count,
                                                         string.Format(Resx.GetLabel(ResxCommon.BARCODE_RESULT_WINDOW_ERROR_FOLDER_LIMIT), Resx.GetLabel(ResxIndexPanel.BARCODE_PAGE_LABEL).ToLower(),
                                                                       Separator.InfLimit, Separator.SupLimit));
                                }
                            }
                        }
                        else
                        {
                            name = string.Format("{0} ({1}) {2}", barcodeName, Documents.Count,
                                                 Separator.UniqueIndexIdentifier != null ? " - " + Separator.UniqueIndexLabel + ": '" + Separator.RecognizedIndexValue + "'" : string.Empty);
                        }

                        //Check Unicity value if folder correspondence activate.                        
                        if ((Separator.CorrespondenceFolder) && (!Separator.RecognizedUniqueIndexValue))
                        {
                            name = name + " " + Resx.GetLabel(ResxCommon.BARCODE_RESULT_WINDOW_ERROR_FOLDER_INDEX_VALUE_NOT_UNIQUE);
                        }

                        //Value to return;
                        if (Separator.ErrorManagment)
                        {
                            return name;
                        }
                        return string.Format("{0} ({1}) {2}", barcodeName, Documents.Count,
                                             Separator.UniqueIndexLabel != null ? " - " + Separator.UniqueIndexLabel + ": '" + Separator.RecognizedIndexValue + "'" : string.Empty);
                    }
                    catch (Exception)
                    {
                        ErrorDocumentLimit = l_bErrorDocument;
                        ErrorPageLimit = l_bErrorPage;
                        return string.Format("{0} ({1}) {2}", Resx.GetLabel(ResxIndexPanel.FOLDER), Documents.Count,
                                             Separator != null ? " - " + Separator.UniqueIndexLabel + ": '" + Separator.RecognizedIndexValue + "'" : string.Empty);
                    }
                }
            }

            /// <summary>
            ///   Gets or sets the separator.
            /// </summary>
            /// <value> The separator. </value>
            public BarcodeFolderSeparator Separator { get; set; }

            #endregion

            #region Instance Methods

            /// <summary>
            ///   Valides the document limit.
            /// </summary>
            /// <returns> </returns>
            public bool ValidateDocumentLimit(int p_iDeleteBarcode = 0)
            {
                if (Separator != null && Separator.DocLimit)
                {
                    if (Separator.InfLimit <= Documents.Count + p_iDeleteBarcode && Documents.Count + p_iDeleteBarcode <= Separator.SupLimit)
                    {
                        return true;
                    }
                    return false;
                }
                return true;
            }

            /// <summary>
            ///   Valides the page limit.
            /// </summary>
            /// <returns> </returns>
            public bool ValidatePageLimit(int p_iDocumentItem = 0)
            {
                if (Separator != null && Separator.PageLimit)
                {
                    if (Separator.InfLimit <= Documents[p_iDocumentItem].ImagesToIndex.Count && Documents[p_iDocumentItem].ImagesToIndex.Count <= Separator.SupLimit)
                    {
                        return true;
                    }
                    return false;
                }
                return true;
            }

            #endregion
        }

        #endregion
    }
}